#include "sleedswindow.h"
#include "ui_sleedswindow.h"
#include "sleefsmodel.h"
#include "sleefsview.h"
#include <QUrl>
#include <QDesktopServices>
#include <QAction>
#include <QFileInfo>
#include <QDebug>
#include <QTimer>
#include <QApplication>



//--------------------------------------------------------------------------------------------------------------------------------------------------------------

SleeDSWindow::SleeDSWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SleeDSWindow)
{
    ui->setupUi(this);

    ui->dockw_fso_process->hide();

    upload_model(ui->fsnav_left, ui->tv_left, "/home/rat/temp");
    upload_model(ui->fsnav_right, ui->tv_right, "/home/rat");

    connect(ui->tv_left, SIGNAL(doubleClicked(QModelIndex)), SLOT(tvitem_act(QModelIndex)));
    connect(ui->tv_right, SIGNAL(doubleClicked(QModelIndex)), SLOT(tvitem_act(QModelIndex)));

    connect(ui->tv_left, SIGNAL(enter_pressed(QModelIndex)), SLOT(tvitem_act(QModelIndex)));
    connect(ui->tv_right, SIGNAL(enter_pressed(QModelIndex)), SLOT(tvitem_act(QModelIndex)));

    connect(ui->tv_left,SIGNAL(tab_pressed(QModelIndex)), SLOT(switch_tv_focus()));
    connect(ui->tv_right,SIGNAL(tab_pressed(QModelIndex)), SLOT(switch_tv_focus()));

    connect(ui->tv_left, SIGNAL(got_focus()), SLOT(set_active_view()));
    connect(ui->tv_right, SIGNAL(got_focus()), SLOT(set_active_view()));


    connect(&m_file_proc, SIGNAL(queue_started(int,qint64)), SLOT(fproc_started(int,qint64)));
    connect(&m_file_proc, SIGNAL(queue_fso_processed(int,int)), SLOT(fproc_processed(int,int)));
    connect(&m_file_proc, SIGNAL(queue_done()), SLOT(fproc_done()));
    connect(&m_file_proc, SIGNAL(queue_done()), ui->tv_left, SLOT(update_view()));
    connect(&m_file_proc, SIGNAL(queue_done()), ui->tv_right, SLOT(update_view()));
    connect(&m_file_proc, SIGNAL(queue_bytes_processed(qint64,qint64)), SLOT(fproc_bytes_done(qint64,qint64)));
    connect(&m_file_proc, SIGNAL(queue_item_started(QString,QString,int)), SLOT(fproc_item_started(QString,QString,int)));
    connect(&m_file_proc, SIGNAL(queue_item_bytes_processed(qint64,qint64)), SLOT(fproc_item_bytes_done(qint64,qint64)));
    connect(&m_file_proc, SIGNAL(queue_item_done(QString,QString)), SLOT(fproc_item_done(QString,QString)));

    QAction *p_act = new QAction(this);
    this->addAction(p_act);
    p_act->setShortcut(QKeySequence("F5"));
    connect(p_act, SIGNAL(triggered()), SLOT(copy_files()));


    p_act = new QAction(this);
    this->addAction(p_act);
    p_act->setShortcut(QKeySequence("F6"));
    connect(p_act, SIGNAL(triggered()), SLOT(move_files()));

    p_act = new QAction(this);
    this->addAction(p_act);
    p_act->setShortcut(QKeySequence("F8"));
    connect(p_act, SIGNAL(triggered()), SLOT(del_files()));
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

SleeDSWindow::~SleeDSWindow()
{
    delete ui;
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::upload_model(FormFSNavigation *p_fsnav,SleeFSView *p_tv, const QString &qstr_root_dir)
{
    if(p_tv->model())
    {
        p_tv->model()->deleteLater();
    }
    QFileSystemModel *p_model = new SleeFSModel(this);
    p_tv->setModel(p_model);

    p_fsnav->set_table_view(p_tv);

    p_tv->setRootIndex(p_model->setRootPath(qstr_root_dir));

    p_tv->sortByColumn(0, Qt::AscendingOrder);

}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::switch_tv_focus()
{
    SleeFSView *p_tv = qobject_cast<SleeFSView *>(sender());
    if(ui->tv_left == p_tv)
    {
        ui->tv_right->setFocus();
    }
    else
    {
        ui->tv_left->setFocus();
    }
}


//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::tvitem_act(QModelIndex index)
{
    SleeFSView *p_tv = qobject_cast<SleeFSView *>(sender());
    SleeFSModel *p_model = dynamic_cast<SleeFSModel *>(p_tv->model());
    if(p_model->isDir(index))
    {
        p_tv->setRootIndex(index);
        p_model->setRootPath(p_model->filePath(index));
    }
    else
    {
        QString absolutePath = p_model->filePath(index);
        QUrl qurl_(QString("file://")+absolutePath, QUrl::TolerantMode);
        if(!QDesktopServices::openUrl(qurl_))
        {
            qDebug()<<Q_FUNC_INFO<<" opening failed:"<<absolutePath;
        }
    }
}


//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::showEvent(QShowEvent *)
{
    ui->tv_right->setFocus();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::set_active_view()
{
    SleeFSView *p_tv = qobject_cast<SleeFSView *>(sender());
    if(ui->tv_left == p_tv)
    {
        ui->tv_right->set_active(false);
        ui->tv_left->set_active(true);
        p_active_tv = ui->tv_left;
    }
    else
    {
        ui->tv_left->set_active(false);
        ui->tv_right->set_active(true);
        p_active_tv = ui->tv_right;
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::copy_files()
{
    SleeFSView *p_tv_src = (ui->tv_left->is_active()) ? ui->tv_left : ui->tv_right;
    SleeFSView *p_tv_dest = (!ui->tv_left->is_active()) ? ui->tv_left : ui->tv_right;

    QStringList qstrl_paths = p_tv_src->selected_paths();
    bool start_processor = false;

    foreach(QString src_fso, qstrl_paths)
    {
        QString dest_fso = p_tv_dest->root_path() + "/";
        dest_fso += QFileInfo(src_fso).fileName();
        if(m_file_proc.add_to_copy(src_fso, dest_fso)) start_processor = true;
    }

    if(!m_file_proc.isRunning() && start_processor) m_file_proc.start();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::del_files()
{
    SleeFSView *p_tv_src = (ui->tv_left->is_active()) ? ui->tv_left : ui->tv_right;

    QStringList qstrl_paths = p_tv_src->selected_paths();
    bool start_processor = false;

    foreach(QString src_fso, qstrl_paths)
    {
        if(m_file_proc.add_to_del(src_fso)) start_processor = true;
    }

    if(!m_file_proc.isRunning() && start_processor) m_file_proc.start();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::move_files()
{
    SleeFSView *p_tv_src = (ui->tv_left->is_active()) ? ui->tv_left : ui->tv_right;
    SleeFSView *p_tv_dest = (!ui->tv_left->is_active()) ? ui->tv_left : ui->tv_right;

    QStringList qstrl_paths = p_tv_src->selected_paths();

    bool start_processor = false;
    foreach(QString src_fso, qstrl_paths)
    {
        QString dest_fso = p_tv_dest->root_path() + "/";
        dest_fso += QFileInfo(src_fso).fileName();
        if(m_file_proc.add_to_move(src_fso, dest_fso)) start_processor = true;
    }

    if(!m_file_proc.isRunning() && start_processor) m_file_proc.start();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_started(int /*count*/, qint64 /*bytes*/)
{
    ui->dockw_fso_process->show();
    ui->pb_bytes_total->setValue(0);
    ui->pb_bytes_total->setFormat("Total: \t %p%");
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_processed(int i, int t)
{
    ui->statusBar->showMessage(QString(" files processed: %1/%2 ").arg(i).arg(t), 10000);
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_done()
{
    ui->pb_bytes_total->setValue(100);
    QTimer *p_timer = new QTimer(this);
    p_timer->setSingleShot(true);
    connect(p_timer, SIGNAL(timeout()), ui->dockw_fso_process, SLOT(hide()));
    p_timer->start(2000);
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_bytes_done(qint64 bytes_done, qint64 bytes_total)
{
    int percent = bytes_done * 100ll / bytes_total;
    ui->pb_bytes_total->setValue(percent);
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_item_started(QString qstr_src, QString qstr_dest, int operation)
{
    QString qstr_op;
    switch (operation)
    {
    case SleeFileProcessor::FSOCopy: qstr_op = "Copy"; break;
    case SleeFileProcessor::FSOMove: qstr_op = "Move"; break;
    case SleeFileProcessor::FSODelete: qstr_op = "Delete"; break;
    case SleeFileProcessor::FSOMakeDir: qstr_op = "MakeDir"; break;
    };
    ui->dockw_fso_process->setWindowTitle(qstr_op + ": " + qstr_src);
    ui->pb_bytes_current->setValue(0);
    ui->pb_bytes_current->setFormat(qstr_dest + ":\t%p%");
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_item_bytes_done(qint64 bytes_done, qint64 bytes_total)
{
    int percent = bytes_done * 100ll / bytes_total;
    ui->pb_bytes_current->setValue(percent);

}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------

void SleeDSWindow::fproc_item_done(QString qstr_src, QString /*qstr_dest*/)
{
    ui->pb_bytes_current->setValue(100);
    qApp->processEvents();
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------
